import Tools.Geometry;

import application.Configuration;

import display3D.*;
import display3D.controller3D.*;
import display3D.objet3D.*;
import display3D.scene3D.*;

import flash.events.Event;
import flash.events.MouseEvent;
import flash.media.Sound;
import flash.media.SoundChannel;
import flash.utils.Dictionary;

import mx.containers.Canvas;
import mx.containers.Panel;
import mx.controls.Alert;
import mx.controls.Button;
import mx.controls.ProgressBar;
import mx.core.DragSource;
import mx.events.DragEvent;
import mx.events.ListEvent;
import mx.managers.DragManager;

import parserXML.XmlConf;
import parserXML.XmlContent;
import parserXML.XmlLinkLink;
import parserXML.XmlLinkRoom;
import parserXML.XmlLoader;
import parserXML.XmlObject;
import parserXML.XmlRoom;

import spark.components.TextArea;


/**
 * Contient les différents parsage des fichiers de configurations xml.
 */
private var configurationXml:XmlConf;

/**
 * True si les fichiers de configuration sont chargés, false sinon.
 * @default false
 */
private var configurationActive:Boolean;

/**
 * Scene 3D
 */
private var scene:Scene3Da;
/**
 * 
 * 
 * VARIABLE POUR GERER LES TRANSITIONS
 * 
 */
private var pointTransition:Array;
private var porteCible:String;
/**
 * 
 * VARIABLE POUR GERER LE MENU
 * 
 */
public var listMusee:Dictionary;
public var listEtage:Dictionary;
public var listSalle:Dictionary;
/**
 * 
 *VARIABLE POUR GERER LE SON 
 * 
 */
private var son:Sound;
private var sonChannel:SoundChannel;
private var sonPlaying:Boolean =false;
private var sonPoint:Number = 0;
private var oeuvreDescrip = Peinture;
var ouvert:Boolean = true;


	/**
	 * <p>Demarre le chargement des fichiers xml de configuration</p>
	 * <p>Creer la scene3D</p>
	 */
	public function initialisation():void
	{
		//Chargement des fichiers xml de configurations
		this.configurationActive = false;
		this.configurationXml = new XmlConf();
		this.configurationXml.addEventListener(XmlConf.COMPLETE_CHARGEMENT,configurationCharge);
		this.configurationXml.chargementConf();
		
		//Creation de la scene 3D
		this.scene = UIHolder;
	}

	
	/**
	 * Active la configuration et rempli le dataProvider des salles
	 * @param evt XmlConf.COMPLETE_CHARGEMENT
	 */
	private function configurationCharge(evt:Event):void
	{
			this.configurationActive =true;
			creationListeMusee();
	}

	/**
	 * Creer la liste des musée
	 */
	private function creationListeMusee():void
	{
		var data:Array = new Array;
	
		for  ( var musee:Object in this.configurationXml.CONF_LINKS_LINK)
		{
			var tabEtage:Array = new Array;
			var item:Object = new Object;
			var vecteur:Vector.<Object> = this.configurationXml.CONF_LINKS_LINK[musee];
			item["label"] = vecteur[0][3];
			item["data"] = vecteur[0][0];
			for each (var etage:Object in vecteur)
			{
				tabEtage.push(etage[2]);
			}
			item["etage"] = tabEtage;
			data.push(item);	
		}
		listeMusee.dataProvider = data;
		
	}

	/**
	 * Créer la liste des étages
	 * @param tabEtage Etage a affiché
	 */
	private function creationListeEtage(tabEtage:Array=null):void
	{
		if (tabEtage!=null)
		{
			var data:Array = new Array;
			
			for  ( var etage:String in tabEtage)
			{
				var tabSalle:Array = new Array;
				var item:Object = new Object;
				var vecteur:Vector.<Object> = this.configurationXml.CONF_LINKS_ROOM[etage];
				item["label"] = vecteur[0][1];
				item["data"] = vecteur[0][0];
				for each (var salle:Object in vecteur)
				{
					tabSalle.push(salle[2]);
				}
				item["salle"] = tabSalle;
				data.push(item);	
			}
			listeEtage.dataProvider = data;
		}
		else
		{
			var data:Array = new Array;
			
			for  ( var etage:String in this.configurationXml.CONF_LINKS_ROOM)
			{
				var tabSalle:Array = new Array;
				var item:Object = new Object;
				var vecteur:Vector.<Object> = this.configurationXml.CONF_LINKS_ROOM[etage];
				item["label"] = vecteur[0][1];
				item["data"] = vecteur[0][0];
				for each (var salle:Object in vecteur)
				{
					tabSalle.push(salle[2]);
				}
				item["salle"] = tabSalle;
				data.push(item);	
			}
			listeEtage.dataProvider = data;
		}
		
	}

	/**
	 * Créer la liste des salles
	 * @param tabSalle Salle de l'étage
	 */
	private function creationListeSalle(tabSalle:Array=null):void
	{
		if (tabSalle!=null)
		{
			var data:Array = new Array;
			var temp:Object = new Object;
			for each( var idLink:String in tabSalle)
			{
				var splitIdLink:Array = idLink.split("_");
				if (temp[splitIdLink[0]]==null)
				{
					var item:Object = new Object;
					var vecteur:Array = this.configurationXml.CONF_ROOM[splitIdLink[0]];
					item["label"] = vecteur[1];
					item["data"] = vecteur[0];
					data.push(item);
					temp[splitIdLink[0]] = 1;
				}
				
			}
			listeSalle.dataProvider = data;
		}
		else
		{
			var data:Array = new Array;
			var temp:Object = new Object;
			for ( var salle:Object in this.configurationXml.CONF_ROOM)
			{
					var item:Object = new Object;
					var vecteur:Array = this.configurationXml.CONF_ROOM[salle];
					item["label"] = vecteur[1];
					item["data"] = vecteur[0];
					data.push(item);
				
			}
			listeSalle.dataProvider = data;
		}
		
	}

	/**
	 * Handler pour le menu des musée
	 * @param event
	 */
	public function listeMusee_changeHandler(event:ListEvent):void
	{
		if (listeMusee.selectedItem!=null)
		{
			creationListeEtage(listeMusee.selectedItem["etage"]);
		}
		else
		{
			creationListeEtage();
		}
		
	}
	
	/**
	 * Handler pour le menu des musée
	 * @param event
	 */
	public function listeEtage_changeHandler(event:ListEvent):void
	{
		if (listeEtage.selectedItem!=null)
		{
			creationListeSalle(listeEtage.selectedItem["salle"]);
		}
		else
		{
			creationListeSalle();
		}
		
	}

	
	/**
	 * Lors du clique sur le bouton valider du musée on lance le chargement de la salle correspondante
	 * @param event
	 */
	public function button1_clickHandler(event:MouseEvent):void
	{
		if (listeSalle.selectedItem!=null)
		{
			creerSalle3DFromMenu(listeSalle.selectedItem["data"]);
		}
		else if (listeEtage.selectedItem!=null)
		{
			var idLink:String = listeEtage.selectedItem["data"];
			var path:String = this.configurationXml.CONF_LINKS_ROOM[idLink][0][3];
			var linkroom:XmlLinkRoom = new XmlLinkRoom("link",path);
			linkroom.addEventListener(XmlObject.CHARGEMENT_COMPLET,chercherRoomStartLinkRoom);
			linkroom.chargementFichier();
		}
		else if (listeMusee.selectedItem!=null)
		{
			var idLink:String = listeMusee.selectedItem["data"];
			var path:String = this.configurationXml.CONF_LINKS_LINK[idLink][0][4];
			var linklink:XmlLinkLink = new XmlLinkLink("link",path);
			linklink.addEventListener(XmlObject.CHARGEMENT_COMPLET,chercherRoomStartLinkLink);
			linklink.chargementFichier();
		}
		else
		{
			Alert.show("Vous n'avez rien sélectionné !!!","Attention !!!");
		}
	}

	/**
	 * Affiche ou cache le panel correspondant 
	 * @param event
	 */
	public function label1_clickHandler(event:MouseEvent):void
	{
		if (panelPresentation.visible == true)
		{
			panelPresentation.visible = false;
		}
		else
		{
			panelPresentation.visible = true;
		}
	}

	/**
	 * Affiche ou cache le panel correspondant 
	 * @param event
	 */
	public function label2_clickHandler(event:MouseEvent):void
	{
		if (panelDescriptionOeuvre.visible == true)
		{
			panelDescriptionOeuvre.visible = false;
		}
		else
		{
			panelDescriptionOeuvre.visible = true;
		}
	}

	/**
	 * Affiche ou cache le panel correspondant 
	 * @param event
	 */
	public function label3_clickHandler(event:MouseEvent):void
	{
		if (panelAide.visible == true)
		{
			panelAide.visible = false;
		}
		else
		{
			panelAide.visible = true;
		}
	}

	/**
	 * Affiche ou cache le panel correspondant 
	 * @param event
	 */
	public function label4_clickHandler(event:MouseEvent):void
	{
		if (panelAPropos.visible == true)
		{
			panelAPropos.visible = false;
		}
		else
		{
			panelAPropos.visible = true;
		}
	}

	
	public function label5_clickHandler(event:MouseEvent):void
	{
		if(ouvert){
			panelPresentation.visible = false;
			panelDescriptionOeuvre.visible = false;
			panelAide.visible = false;
			panelAPropos.visible = false;
			ouvert = false;
		}
		else{
			panelPresentation.visible = true;
			panelDescriptionOeuvre.visible = true;
			panelAide.visible = true;
			panelAPropos.visible = true;
			ouvert = true;
		}
	}

	private function chercherRoomStartLinkRoom(evt:Event):void
	{
		var linkroomXml:XmlLinkRoom = evt.target;
		creerSalle3DFromMenu(linkroomXml.start_room);
	}

	private function chercherRoomStartLinkLink(evt:Event):void
	{
		var linklink:XmlLinkLink = evt.target;
		creerSalle3DFromMenu(linklink.start_room);
	}

	/**
	 * Creer une salle 3D à partir de son identifiant et à partir du menu
	 * @param id identifiant de la salle
	 */
	private function creerSalle3DFromMenu(id_salle:String):void
	{
		if (this.configurationActive){
			if (scene.currentSalle!=null)
			{
				scene.supprimerTout();
				scene.currentSalle = null;
				scene.oldSalle =null;
				scene.nextSalle=null;
			}
			var path:String = this.configurationXml.CONF_ROOM[id_salle][2];
			var roomXml:XmlRoom = new XmlRoom("room",path);
			roomXml.addEventListener(XmlObject.CHARGEMENT_COMPLET,chargerSalle);
			roomXml.chargementFichier();
		}
		
	}
	
	/**
	 * Creer une salle 3D à partir de son identifiant
	 * @param id identifiant de la salle
	 */
	private function creerSalle3D(id:String):void
	{
		if (this.configurationActive){
			var path:String = this.configurationXml.CONF_ROOM[id][2];
			var roomXml:XmlRoom = new XmlRoom("room",path);
			roomXml.addEventListener(XmlObject.CHARGEMENT_COMPLET,chargerSalle);
			roomXml.chargementFichier();
		}
	
	}

	/**
	 * Charge le fichier xml d'une salle et creer une salle 3D
	 * @param evt XmlObject.CHARGEMENT_COMPLET
	 */
	private function chargerSalle(evt:Event):void
	{
		var roomXml:XmlRoom = evt.target;
		var vectMurs:Vector.<Object> = roomXml.murs;
		var vectMursRes:Vector.<Mur> = new Vector.<Mur>;
		for (var i:int=0;i<vectMurs.length;i++)
		{
			//Creation du mur
			var mur:Mur = new Mur(vectMurs[i][0],vectMurs[i][1],vectMurs[i][2],vectMurs[i][3]);
			
			//Creation des oeuvres du mur
			var dictOeuvres:Dictionary = new Dictionary;
			var vectOeuvres:Vector.<Object> = vectMurs[i][4];
			for (var j:int=0;j<vectOeuvres.length;j++)
			{
				var id:String = vectOeuvres[j][0];
				if(id == "")
					continue;
				var type:String = vectOeuvres[j][1];
				var x:Number =  vectOeuvres[j][2];
				var y:Number =  vectOeuvres[j][3];
				var desc:String =  vectOeuvres[j][4];
				var src:String =  vectOeuvres[j][5];
				var peinture:Peinture = new Peinture(id,type,desc,x,y,src);
				peinture.soundPath = vectOeuvres[j][6];
				peinture.addEventListener(Peinture.OEUVRE_PROXIMITE,oeuvreDetecter);
				peinture.addEventListener(Peinture.CLICK_PEINTURE,oeuvreDetecter);
				dictOeuvres[id]=peinture;
			}
			
			//Creation des portes du mur
			var vectPortes:Vector.<Object> = vectMurs[i][5];
			var dictPortes:Dictionary = new Dictionary;
			for (var k:int=0;k<vectPortes.length;k++)
			{
				
				var id:String = vectPortes[k][0];
				if(id == "")
					continue;
				var type:String = vectPortes[k][1];
				var x:Number =  vectPortes[k][2];
				var y:Number =  vectPortes[k][3];
				var porte:Porte = new Porte(id,type,x,y);
				porte.transition.id = vectPortes[k][4];
				dictPortes[id] = porte;
			}
			
			//Envoi des chargement des cibles de la porte et creation des transition
			chargerTransition(roomXml.id,dictPortes);
			
			mur.oeuvres = dictOeuvres;
			mur.portes = dictPortes;
			vectMursRes.push(mur);
		}
		
		//On calcul maintenant les 4 murs les plus espacé pour dessiner le sol et le plafond
		var point1:Array = new Array();
		var point2:Array = new Array();
		var distanceTemp1:Number = 0;
		for each (var mur:Mur in vectMursRes)
		{
			for each (var mur2:Mur in vectMursRes)
			{	
				var distanceCalc = Geometry.distance(mur.x1,mur.y1,mur2.x2,mur2.y2);
				if (distanceTemp1 <= distanceCalc)
				{
					distanceTemp1 = distanceCalc;
					point1[0] = mur.x1;
					point1[1] = mur.y1;
					point2[0] = mur2.x2;
					point2[1] = mur2.y2;
				}
			}
		}
		var pointM:Array = new Array();
		pointM[0] = (point1[0]+point2[0])/2 ; 
		pointM[1] = (point1[1]+point2[1])/2 ;
		var floor:Floor = new Floor(pointM[0],pointM[1],0,distanceTemp1);
		var roof:Roof = new Roof(pointM[0],pointM[1],Mur.hauteur,distanceTemp1);
		var salle3D:Salle3D = new Salle3D(roomXml.id,roomXml.name,roomXml.x_camera,roomXml.y_camera,vectMursRes,floor,roof);
		if (scene.currentSalle == null)
		{
			scene.currentSalle = salle3D;
			scene.afficheSalle();
		}
		else{
			var porte:Porte = salle3D.getPorteById(porteCible);
			var pointArrive = new Array;
			pointArrive[0] = porte.x;
			pointArrive[1] = porte.y;
			salle3D.transformation(pointArrive,pointTransition,porteCible);
			scene.nextSalle = null;
			scene.oldSalle =scene.currentSalle;
			scene.currentSalle = salle3D;
			scene.afficheNext(porteCible);
		}
		
	}


	/**
	 *  Lance le chargement des transition et des cible d'une porte
	 * @param vectPortes 
	 */
	private function chargerTransition(idSalle:String,dictPortes:Dictionary):void
	{
		var linkedRoom:Boolean = false;
		var linkedLink:Boolean = false;
		var pathLinkedRoom:String;
		var pathLinkedLink:String;
		
		for each(var porte:Porte in dictPortes)
		{
			if (this.configurationXml.CONF_LINKS_ROOM_BY_ID_LINK[idSalle+"_"+porte.id])
			{
				linkedRoom = true;
				pathLinkedRoom = this.configurationXml.CONF_LINKS_ROOM_BY_ID_LINK[idSalle+"_"+porte.id][3];
			}
			else if (this.configurationXml.CONF_LINKS_LINK_BY_ID_LINK[idSalle+"_"+porte.id])
			{
				linkedLink = true;
				pathLinkedLink = this.configurationXml.CONF_LINKS_LINK_BY_ID_LINK[idSalle+"_"+porte.id][4];
			}
		}
		
		if (linkedRoom)
		{
			var xmlLinkRoom:XmlLinkRoom = new XmlLinkRoom("link_room",pathLinkedRoom);
			xmlLinkRoom.addEventListener(XmlObject.CHARGEMENT_COMPLET,chargerCibleLinkRoom);
			xmlLinkRoom.chargementFichier();
			
		}
		else if(linkedLink)
		{
			var xmlLinkLink:XmlLinkLink = new XmlLinkLink("link_room",pathLinkedLink);
			xmlLinkLink.addEventListener(XmlObject.CHARGEMENT_COMPLET,chargerCibleLinkLink);
			xmlLinkLink.chargementFichier();
		}
		
		
	}

	/**
	 * Charge les cible pour les portes
	 * @param evt
	 */
	private function chargerCibleLinkRoom(evt:Event):void
	{
		
		var linkRooms:XmlLinkRoom = evt.target;
		
		for (var i:int=0;i<linkRooms.link.length;i++)
		{
			var link:Array = linkRooms.link[i][1];
			var idLink:String = linkRooms.link[i][0];
			var splitIdLink:Array = idLink.split("_");
			if (scene.currentSalle.id == link[0][0] && scene.currentSalle.id == splitIdLink[0])
			{
				var porte:Porte = scene.currentSalle.getPorteById(link[0][1]);
				if (porte!=null)
				{
					porte.salleCible = link[1][0];
					porte.porteCible = link[1][1];
					porte.charge = true;
					porte.indiquerDirection(this.configurationXml.CONF_ROOM[porte.salleCible][1]);
					porte.addEventListener(Porte.PORTE_OUVERTE,porteOuverte);
				}
			}
			else if ((scene.currentSalle.id) == link[1][0] && scene.currentSalle.id == splitIdLink[0])
			{
				var porte:Porte = scene.currentSalle.getPorteById(link[1][1]);
				if (porte != null)
				{
					porte.salleCible = link[0][0];
					porte.porteCible = link[0][1];
					porte.charge = true;
					porte.indiquerDirection(this.configurationXml.CONF_ROOM[porte.salleCible][1]);
					porte.addEventListener(Porte.PORTE_OUVERTE,porteOuverte);
				}
			}
		}
	}

	/**
	 * Charge les cible pour les portes
	 * @param evt
	 */
	private function chargerCibleLinkLink(evt:Event):void
	{
		var linkLinks:XmlLinkLink = evt.target;
		
		for (var i:int=0;i<linkLinks.link.length;i++)
		{
			var link:Array = linkLinks.link[i][1];
			
			if (scene.currentSalle.id == link[0][0])
			{
				var porte:Porte = scene.currentSalle.getPorteById(link[0][1]);
				if (porte!=null)
				{
					porte.salleCible = link[1][0];
					porte.porteCible = link[1][1];
					porte.charge = true;
					porte.indiquerDirection(this.configurationXml.CONF_ROOM[porte.salleCible][1]);
					porte.addEventListener(Porte.PORTE_OUVERTE,porteOuverte);
				}
			}
			else if ((scene.currentSalle.id) == link[1][0])
			{
				var porte:Porte = scene.currentSalle.getPorteById(link[1][1]);
				if (porte != null)
				{
					porte.salleCible = link[0][0];
					porte.porteCible = link[0][1];
					porte.charge = true;
					porte.indiquerDirection(this.configurationXml.CONF_ROOM[porte.salleCible][1]);
					porte.addEventListener(Porte.PORTE_OUVERTE,porteOuverte);
				}
			}
		}
	}

	/**
	 * Lorsque une porte est ouverte et lorsqu'un point de transition est touché
	 * @param evt
	 */
	private function porteOuverte(evt:Event):void
	{
		var porte:Porte = evt.target;
		porte.removeEventListener(Porte.PORTE_OUVERTE,porteOuverte);
		pointTransition = new Array;
		pointTransition[0] = porte.transition.pointX;
		pointTransition[1] = porte.transition.pointY;
		pointTransition[2] = porte.transition.vecteurNormMur;
		porteCible = porte.porteCible;
		creerSalle3D(porte.salleCible);
	}

	/**
	 * Lorsqu'une oeuvre est detectée
	 * @param evt
	 */
	private function oeuvreDetecter(evt:Event):void
	{
		if (oeuvreDescrip==null || evt.target != oeuvreDescrip)
		{
			oeuvreDescrip = evt.target;
			textDescriptionOeuvre.text = oeuvreDescrip.description;
			vBoxSound.visible=false;
			
			panelDescriptionOeuvre.visible = true;
			if (sonChannel!=null && son !=null)
			{
				sonChannel.stop();
				sonPoint = 0;
				sonPlaying = false;
				playSound.label = "Lire";
			}
			if (oeuvreDescrip.soundPath!="")
			{
				vBoxSound.visible=true;
				son = new Sound();
				son.load(new URLRequest(oeuvreDescrip.soundPath), new SoundLoaderContext(10000));
				
			}else{
				vBoxSound.visible =false;
			}
		}
	}


	/**
	 * Gère la lecture du son
	 * @param event
	 */
	protected function button2_clickHandler(event:MouseEvent):void
	{
		if (sonPlaying) {
			sonPoint = sonChannel.position;
			sonChannel.stop();
			sonPlaying = false;
			playSound.label = "Lire";
		} else {
			sonChannel = son.play(sonPoint);
			sonPlaying = true;
			playSound.label = "Pause";
		}
		
		
	}
	
	
	/**
	 * Gère la lecture du son
	 * @param event
	 */
	protected function button3_clickHandler(event:MouseEvent):void
	{
		if (sonPlaying) {
			sonChannel.stop();
			sonPlaying = false;
			playSound.label = "Lire";
		}
		sonPoint = 0;
	}

	/**
	 * 
	 * 
	 * 
	 * GESTION DES PANELS DU MXML POUR AUTORISER LE DRAG AND DROP
	 * RECUPERER SUR INTERNET
	 * 
	 * 
	 * 
	 */ 

	// Define static constant for event type.
	public static const RESIZE_CLICK:String = "resizeClick";
	
	// Creation complete event handler adds the resizing event. 
	// resizeButtonClicked is a custom event type for this application.
	public function creationCompleteHandler():void
	{
		addEventListener(RESIZE_CLICK, resizeHandler);
	}
	
	//
	// D&D event handlers.
	//
	
	// Creation complete handler for each panel to add the 
	// mouseMove event handler to the title bar. 
	// Clicking the mouse button, then moving the mouse on the title bar
	// initiates the d&d operation. 
	public function myPanelCCHandler(event:Event):void 
	{
		event.currentTarget.myTitleBar.addEventListener(MouseEvent.MOUSE_DOWN, tbMouseMoveHandler);
	}
	
	// Variables used to hold the mouse pointer's location in the title bar.
	// Since the mouse pointer can be anywhere in the title bar, you have to 
	// compensate for it when you drop the panel. 
	public var xOff:Number;
	public var yOff:Number;
	
	// Function called by the canvas dragEnter event; enables dropping
	public function doDragEnter(event:DragEvent):void 
	{
		DragManager.acceptDragDrop(Canvas(event.target));
	}
	
	// Drag initiator event handler for
	// the title bar's mouseMove event.
	public function tbMouseMoveHandler(event:MouseEvent):void 
	{
		var dragInitiator:Panel=Panel(event.currentTarget.parent);
		var ds:DragSource = new DragSource();
		ds.addData(event.currentTarget.parent, 'panel'); 
		
		// Update the xOff and yOff variables to show the
		// current mouse location in the Panel.  
		xOff = event.currentTarget.mouseX;
		yOff = event.currentTarget.mouseY;
		
		// Initiate d&d. 
		DragManager.doDrag(dragInitiator, ds, event);                    
	}            
	
	// Function called by the Canvas dragDrop event; 
	// Sets the panel's position, 
	// "dropping" it in its new location.
	public function doDragDrop(event:DragEvent):void 
	{
		// Compensate for the mouse pointer's location in the title bar.
		var tempX:int = event.currentTarget.mouseX - xOff;
		event.dragInitiator.x = tempX;
		
		var tempY:int = event.currentTarget.mouseY - yOff;
		event.dragInitiator.y = tempY;
		
		// Put the dragged panel on top of all other components.
		v1.setChildIndex(Panel(event.dragInitiator), v1.numChildren-1);			
	}
	
	//
	// Resizing event handlers.
	//
	
	// Save panel being resized.
public var resizingPanel:Panel;
	// Global coordinates of lower left corner of panel.
public var initX:Number;
public var initY:Number;
	
	// Resize area of panel clicked.
public function resizeHandler(event:MouseEvent):void
	{
		resizingPanel = Panel(event.target);
		initX = event.localX;
		initY = event.localY;
		
		// Place the rubber band over the panel. 
		rbComp.x = event.target.x;
		rbComp.y = event.target.y;
		rbComp.height = event.target.height;
		rbComp.width = event.target.width;
		
		// Make sure rubber band is on top of all other components.
		v1.setChildIndex(rbComp, v1.numChildren-1);
		rbComp.visible=true;
		
		// Add event handlers so that the SystemManager handles 
		// the mouseMove and mouseUp events. 
		// Set useCapure flag to true to handle these events 
		// during the capture phase so no other component tries to handle them.
		systemManager.addEventListener(MouseEvent.MOUSE_MOVE, mouseMoveHandler, true);
		systemManager.addEventListener(MouseEvent.MOUSE_UP, mouseUpHandler, true);
	}
	
	// Resizes the rubber band as the user moves the cursor 
	// with the mouse key down.
public function mouseMoveHandler(event:MouseEvent):void
	{
		event.stopImmediatePropagation();		
		
		rbComp.height = rbComp.height + event.stageY - initY;  
		rbComp.width = rbComp.width + event.stageX - initX;
		
		initX = event.stageX;
		initY = event.stageY;						
	}
	
	// Sizes the panel to the size of the rubber band when the 
	// user releases the mouse key. 
	// Also removes the event handlers from the SystemManager.
public function mouseUpHandler(event:MouseEvent):void
	{
		event.stopImmediatePropagation();		
		
		// Use a minimum panel size of 150 x 50.
		if (rbComp.height <= 50)
		{
			resizingPanel.height = 50;  
		}
		else
		{
			resizingPanel.height = rbComp.height;  				
		}				
		
		if (rbComp.width <= 150)
		{
			resizingPanel.width = 150;				
		}
		else
		{
			resizingPanel.width = rbComp.width;				
		}				
		
		// Put the resized panel on top of all other components.
		v1.setChildIndex(resizingPanel, v1.numChildren-1);
		
		// Hide the rubber band until next time.
		rbComp.x = 0;
		rbComp.y = 0;
		rbComp.height = 0;
		rbComp.width = 0;
		rbComp.visible = false;
		
		systemManager.removeEventListener(MouseEvent.MOUSE_MOVE, mouseMoveHandler, true);
		systemManager.removeEventListener(MouseEvent.MOUSE_UP, mouseUpHandler, true	);
	}

